package com.ruoyi.common.core.utils;

import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.TokenConstants;
import com.ruoyi.common.core.text.Convert;
import io.jsonwebtoken.*;

import java.util.Map;

/**
 * Jwt工具类
 *
 * @author ruoyi
 */
public class JwtUtils {
    public static String secret = TokenConstants.SECRET;

    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    public static String createToken(Map<String, Object> claims) {
        JwtBuilder builder = Jwts.builder();  // 创建JwtBuilder对象，用于创建JWT
        JwtBuilder jwtBuilder = builder.setClaims(claims);  // 设置数据声明
        JwtBuilder jwtBuilder1 = jwtBuilder.signWith(SignatureAlgorithm.HS512, secret);  // 设置签名密钥
        String token = jwtBuilder1.compact();  // 生成令牌
        return token;
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims parseToken(String token) {
        // 该函数使用JWT（JSON Web Token）解析库Jwts解析给定的token。它使用给定的密钥（secret）来验证签名，并返回解析后的JWT声明（claims）。
        JwtParser parser = Jwts.parser(); // 创建一个JwtParser对象，用于解析给定的token
        parser.setSigningKey(secret); // 设置签名密钥
        Jws<Claims> claimsJws = parser.parseClaimsJws(token);  // 解析给定的token
        Claims claims = claimsJws.getBody();  // 获取解析后的JWT声明（claims）
        return claims;
    }

    /**
     * 根据令牌获取用户标识
     *
     * @param token 令牌
     * @return 用户ID
     */
    public static String getUserKey(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.USER_KEY);
    }

    /**
     * 根据令牌获取用户标识
     *
     * @param claims 身份信息
     * @return 用户ID
     */
    public static String getUserKey(Claims claims) {
        return getValue(claims, SecurityConstants.USER_KEY);
    }

    /**
     * 根据令牌获取用户ID
     *
     * @param token 令牌
     * @return 用户ID
     */
    public static String getUserId(String token) {
        Claims claims = parseToken(token);
        return getValue(claims, SecurityConstants.DETAILS_USER_ID);
    }

    /**
     * 根据身份信息获取用户ID
     *
     * @param claims 身份信息
     * @return 用户ID
     */
    public static String getUserId(Claims claims) {
        return getValue(claims, SecurityConstants.DETAILS_USER_ID);
    }

    /**
     * 根据令牌获取用户名
     *
     * @param token 令牌
     * @return 用户名
     */
    public static String getUserName(String token) {
        Claims claims = parseToken(token);  // 获取身份信息  数据声明
        return getValue(claims, SecurityConstants.DETAILS_USERNAME);  // 根据声明获取值
    }

    /**
     * 根据身份信息获取用户名
     *
     * @param claims 身份信息
     * @return 用户名
     */
    public static String getUserName(Claims claims) {
        return getValue(claims, SecurityConstants.DETAILS_USERNAME);
    }

    /**
     * 根据身份信息获取键值
     *
     * @param claims 身份信息
     * @param key    键
     * @return 值
     */
    public static String getValue(Claims claims, String key) {
        Object o = claims.get(key);  // 从声明中获取指定键映射到的值，如果此映射不包含该键的映射，则返回 null
        return Convert.toStr(o, "");  // 转换为字符串返回
    }
}
